<?php
require_once "utils.php";

class ManageArchive {
    public static function doCreat() {
        $m = new Messages();
        if (Client::hasCommand("creat") && isset($_POST["title"]) && isset($_POST["content"])) {
            $title = $_POST["title"];
            $content = $_POST["content"];
            $m = ManageArchive::checkCreat($title,$content);
            if ($m->hasMessage()) return $m;
            if ($_SESSION['login']=='anonyme') return new Messages ('Please Login!', 302); //force login to edit
            if (Archive::readArchive($title)) return new Messages('Same title existed. You should look at it.',604);
            Archive::newArchive($title, $content);
            return new Messages('read.php?n='.str_replace(' ','_',$title), 501);
        }
        return $m;
    }

    public static function doEdit() {
        $m = new Messages();
        if (Client::hasCommand("edit") && isset($_POST["title"]) && isset($_POST["content"]) && isset($_POST['vid'])) {
            $title = $_POST["title"];
            $content = $_POST["content"];
            $vid = $_POST["vid"];
            $m1 = ManageArchive::checkCreat($title,$content);
            if ($m1->hasMessage()) return $m1;
            if ($_SESSION['login']=='anonyme') return new Messages ('Please Login!', 302); //force login to edit
            $m2 = Archive::updateArchive(new Archive(array('',$title,$content,$vid)));
            if ($m2->hasMessage()) return $m2;
            return new Messages('read.php?n='.str_replace(' ','_',$title), 501);
        }
        return $m;
    }

    public static function doRead() {
        $m = new Messages();
        if (Client::hasCommand("n")) {
            $a = Archive::readArchive(str_replace('_', ' ', $_GET['n']));
            if (!$a) return new Messages('This article doesn\'t exist. Do you want to creat it?', 607);
            return $a;
        }
        return $m;
    }

    public static function checkCreat($title,$content) {
        $m = new Messages();
        if (str_replace(' ', '', $title)=='') $m->pushMessage ('title can\'t not be null', 605);
        if (str_replace(' ', '', $content)=='') $m->pushMessage ('content can\'t not be null', 606);
        return $m;
    }

    public static function doSearch() { //quite slow
        $m = new Messages();
        if (Client::hasCommand('q')) {
            $q = $_GET['q'];
            $dbh = Database::connect();
            $query = "SELECT `title` FROM `archive` WHERE `title` LIKE ? OR `content` LIKE ?";
            $sth = $dbh->prepare($query);
            $sth->execute(array("%{$q}%","%{$q}%"));
            $sth->setFetchMode(PDO::FETCH_CLASS, 'Archive');
            $output = $sth->fetchAll();
            return $output;
        }

    }
}

class Archive {
    public $aid;
    public $title;
    public $content;
    public $vid;

    public function  __construct($arg=array()) {
        $rfc = new ReflectionClass('Archive');
        $rfp = $rfc->getProperties();
        $fillLength = min(sizeof($rfp),sizeof($arg));
        for ($i=0;$i<$fillLength;$i++) $rfp[$i]->setValue($this,$arg[$i]);
    }

    public static function newArchive($title,$content){

        require_once 'Diff.php';
        $vContent=Text_Diff::getVersion('', $content);

        $version = new Version(array($title,$vContent,$_SESSION["login"],date("y/m/d : H:i:s", time()),0));
        $maxVid = Version::insertVersion($version);
        
        $dbh = Database::connect();
        $query = "INSERT INTO `archive` (`title`,`content`,`vid`) VALUES(?,?,?)";
        $sth = $dbh->prepare($query);
        $sth->execute(array($title,$content,$maxVid));

    }
    
    public static function updateArchive($updated_archive) {
        $m = new Messages();
        if ($_SESSION['login']=='anonyme') return new Messages ('Please Login!', 302); //force login to edit
        $dbh = Database::connect();
        $query = "SELECT * FROM `archive` WHERE `vid` = ?";
        $sth = $dbh->prepare($query);
        $sth->execute(array($updated_archive->vid));
        $sth->setFetchMode(PDO::FETCH_CLASS, 'Archive');
        $archive = $sth->fetch(PDO::FETCH_CLASS);
        require_once 'Diff.php';
        
        if ($archive) { //update the archive
            if ($updated_archive->title == $archive->title && $updated_archive->content == $archive->content) return new Messages ('You didn\'t make any change.',601);
            $vContent = Text_Diff::getVersion($archive->content,$updated_archive->content   );
            $version = new Version(array($updated_archive->title,$vContent,$_SESSION["login"],date("y/m/d : H:i:s", time()),$archive->vid));
            $maxVid = Version::insertVersion($version);

            $query = "UPDATE  `archive` SET `title`=?,`content`=?,vid=? WHERE `aid` = ?";
            $sth = $dbh->prepare($query);
            $sth->execute(array($updated_archive->title,$updated_archive->content,$maxVid,$archive->aid));
        } else {
            return new Messages('While you were editing, new version has been created. You should look at it.',603);
        }
        return $m;

    }

    private static function deleteArchive() {}

    public static function readArchive($title) {
        $dbh = Database::connect();
        $query = "SELECT * FROM `archive` WHERE `title` = ?";
        $sth = $dbh->prepare($query);
        $sth->execute(array($title));
        $sth->setFetchMode(PDO::FETCH_CLASS, 'Archive');
        $archive = $sth->fetch(PDO::FETCH_CLASS);
        if ($sth) return $archive; else return null;
    }

    public function setTitle($title) {$this->title=$title;}

    public function setContent($content) {$this->content=$content;}

    public function getTitle() {return $this->title;}

    public function getContent() {return $this->content;}

    public function getLastModified() {
        $dbh = Database::connect();
        $sth = $dbh->prepare("SELECT `time` FROM `version` WHERE `vid`=?");
        $sth->execute(array($this->vid));
        $time = $sth->fetch();
        return $time[0];
    }

    public function getVid() {return $this->vid;}

}

class Version {
    public $title;
    public $content;
    public $login; //creator
    public $time;
    public $p_vid;

    public function  __construct($arg=array()) {
        $rfc = new ReflectionClass('Version');
        $rfp = $rfc->getProperties();
        $fillLength = min(sizeof($rfp),sizeof($arg));
        for ($i=0;$i<$fillLength;$i++) $rfp[$i]->setValue($this,$arg[$i]);
    }

    public static function insertVersion($version) {
        $dbh = Database::connect();
        $parray = (array)$version;
        $keyString = "";
        $valueString ="";
        $first = true;
        foreach ($parray as $key => $value) {
            $keyString .= ($first?"":", ")."`".$key."`";
            $valueString .= ($first?"":", ")."?";
            $first = false;
        }
        $query = "INSERT INTO `version` (".$keyString.") VALUES(".$valueString.")";
        $sth = $dbh->prepare($query);
        $sth->execute(array_values($parray));

        $sth = $dbh->prepare("SELECT MAX(`vid`) FROM `version`");
        $sth->execute();
        $vid = $sth->fetch();
        return $vid[0];
    }

}

?>
